package org.jupiter.blog.service.service.impl;

import org.jupiter.blog.api.convertor.JupiterUserStructConvertor;
import org.jupiter.blog.api.domain.JupiterUser;
import org.jupiter.blog.api.dto.JupiterUserDTO;
import org.jupiter.blog.common.utils.PasswordUtil;
import org.jupiter.blog.service.mapper.JupiterUserMapper;
import org.jupiter.blog.service.service.JupiterUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@Service
public class JupiterUserServiceImpl implements JupiterUserService {

	@Autowired
	private JupiterUserMapper userMapper;

	@Autowired
	private JupiterUserStructConvertor userConvertor;

	@Override
	@Transactional
	public void createUser(JupiterUserDTO dto) throws Exception {
		JupiterUser user = userConvertor.toEntity(dto);
		if (!StringUtils.hasText(user.getUuid())){
			user.setUuid(UUID.randomUUID().toString());
		}
		user.setCreateTime(LocalDateTime.now());
		user.setUpdateTime(LocalDateTime.now());
		user.setPasswordHash(PasswordUtil.hashToDBPassword(user.getPasswordHash()));
		userMapper.insert(user);
	}

	@Override
	@Transactional(readOnly = true)
	public JupiterUserDTO getById(String uuid) {
		JupiterUser user = userMapper.selectByUuid(uuid);
		return userConvertor.toDto(user);
	}

	@Override
	@Transactional(readOnly = true)
	public JupiterUserDTO getByUsernameOrEmail(String username, String email) {
		JupiterUser user = userMapper.selectByUsernameOrEmail(username, email);
		return userConvertor.toDto(user);
	}

	@Override
	@Transactional
	public void updateUser(String uuid, JupiterUserDTO dto) throws Exception {
		JupiterUser user = userConvertor.toEntity(dto);
		user.setUuid(uuid);
		user.setUpdateTime(LocalDateTime.now());
		if (StringUtils.hasText(user.getPasswordHash())){
			user.setPasswordHash(PasswordUtil.hashToDBPassword(user.getPasswordHash()));
		}
		userMapper.updateByUuidSelective(user);
	}

	@Override
	@Transactional
	public void deleteUser(String uuid) {
		userMapper.deleteByUuid(uuid);
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterUserDTO> getByPage(JupiterUserDTO queryDTO) {
		int offset = (queryDTO.getPage() - 1) * queryDTO.getSize();
		List<JupiterUser> users = userMapper.selectByPage(
				queryDTO.getUsername(),
				queryDTO.getNickname(),
				queryDTO.getEmail(),
				queryDTO.getIsActive(),
				offset,
				queryDTO.getSize()
		);
		return userConvertor.toDtoList(users);
	}

	@Override
	@Transactional(readOnly = true)
	public long getCount(JupiterUserDTO queryDTO) {
		return userMapper.countByQuery(
				queryDTO.getUsername(),
				queryDTO.getNickname(),
				queryDTO.getEmail(),
				queryDTO.getIsActive()
		);
	}

	@Override
	@Transactional
	public void updateStatus(String uuid, Integer status) throws Exception {
		JupiterUser user = new JupiterUser();
		user.setUuid(uuid);
		user.setUpdateTime(LocalDateTime.now());
		if (StringUtils.hasText(user.getPasswordHash())){
			user.setPasswordHash(PasswordUtil.hashToDBPassword(user.getPasswordHash()));
		}
		userMapper.updateByUuidSelective(user);
	}

	@Override
	@Transactional
	public void resetPassword(String uuid) throws Exception {
		// 默认密码为123456
		String defaultPassword = "123456";
		JupiterUser user = new JupiterUser();
		user.setUuid(uuid);
		user.setPasswordHash(defaultPassword);
		user.setUpdateTime(LocalDateTime.now());
		if (StringUtils.hasText(user.getPasswordHash())){
			user.setPasswordHash(PasswordUtil.hashToDBPassword(user.getPasswordHash()));
		}
		userMapper.updateByUuidSelective(user);
	}

	@Override
	@Transactional
	public void restoreUser(String uuid) {
		userMapper.restoreUser(uuid);
	}

	@Override
	@Transactional(readOnly = true)
	public boolean existsByUsername(String username) {
		return userMapper.countByUsername(username) > 0;
	}

	@Override
	@Transactional(readOnly = true)
	public boolean existsByEmail(String email) {
		return userMapper.countByEmail(email) > 0;
	}
}
